/******************************************************************************* * Copyright (c) 2000, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.ui.internal; import java.io.IOException; import java.io.OutputStream; import java.util.Collection; import java.util.HashSet; import java.util.Hashtable; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.equinox.http.registry.HttpContextExtensionService; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceManager; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.jface.window.Window; import org.eclipse.osgi.service.localization.LocaleProvider; import org.eclipse.rap.ui.internal.SessionLocaleProvider; import org.eclipse.rap.ui.internal.application.ApplicationRegistry; import org.eclipse.rap.ui.internal.branding.BrandingExtension; import org.eclipse.rap.ui.internal.progress.JobManagerAdapter; import org.eclipse.rap.ui.internal.servlet.EntryPointExtension; import org.eclipse.rap.ui.internal.servlet.HttpServiceTracker; import org.eclipse.rwt.RWT; import org.eclipse.rwt.SessionSingletonBase; import org.eclipse.rwt.service.ISessionStore; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.ui.IEditorRegistry; import org.eclipse.ui.IElementFactory; import org.eclipse.ui.IPerspectiveRegistry; import org.eclipse.ui.ISharedImages; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkingSetManager; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.internal.StartupThreading.StartupRunnable; import org.eclipse.ui.internal.decorators.DecoratorManager; import org.eclipse.ui.internal.dialogs.WorkbenchPreferenceManager; import org.eclipse.ui.internal.intro.IIntroRegistry; import org.eclipse.ui.internal.intro.IntroRegistry; import org.eclipse.ui.internal.misc.StatusUtil; import org.eclipse.ui.internal.operations.WorkbenchOperationSupport; import org.eclipse.ui.internal.progress.ProgressManager; import org.eclipse.ui.internal.registry.ActionSetRegistry; import org.eclipse.ui.internal.registry.EditorRegistry; import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants; import org.eclipse.ui.internal.registry.PerspectiveRegistry; import org.eclipse.ui.internal.registry.PreferencePageRegistryReader; import org.eclipse.ui.internal.registry.ViewRegistry; import org.eclipse.ui.internal.registry.WorkingSetRegistry; import org.eclipse.ui.internal.themes.IThemeRegistry; import org.eclipse.ui.internal.themes.ThemeRegistry; import org.eclipse.ui.internal.themes.ThemeRegistryReader; import org.eclipse.ui.internal.util.BundleUtility; import org.eclipse.ui.internal.wizards.ExportWizardRegistry; import org.eclipse.ui.internal.wizards.ImportWizardRegistry; import org.eclipse.ui.internal.wizards.NewWizardRegistry; import org.eclipse.ui.operations.IWorkbenchOperationSupport; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.eclipse.ui.presentations.AbstractPresentationFactory; import org.eclipse.ui.views.IViewRegistry; import org.eclipse.ui.wizards.IWizardRegistry; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleEvent; import org.osgi.framework.BundleListener; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration; import org.osgi.framework.SynchronousBundleListener; import org.osgi.util.tracker.ServiceTracker; import com.ibm.icu.text.MessageFormat; /** * This class represents the TOP of the workbench UI world * A plugin class is effectively an application wrapper * for a plugin & its classes. This class should be thought * of as the workbench UI's application class. * * This class is responsible for tracking various registries * font, preference, graphics, dialog store. * * This class is explicitly referenced by the * workbench plugin's "plugin.xml" and places it * into the UI start extension point of the main * overall application harness * * When is this class started? * When the Application * calls createExecutableExtension to create an executable * instance of our workbench class. * */ public class WorkbenchPlugin extends AbstractUIPlugin { // RAP [rh] SessionStore key to initicate whether the session-scoped // PerspectiveRegistry is initialized private static final String PERSP_REGISTRY_INITIALIZED = PerspectiveRegistry.class + "#initialized"; // TODO [bm]: turn into real session scoped manager // RAP [rs]: private final static class DecoratorManagerStore extends SessionSingletonBase { private final DecoratorManager decoratorManager; private DecoratorManagerStore() { decoratorManager = new DecoratorManager(); } public static DecoratorManagerStore getInstance() { Class clazz = DecoratorManagerStore.class; return (DecoratorManagerStore) getInstance(clazz); } public DecoratorManager getDecoratorManager() { return decoratorManager; } } // RAPEND] // RAP [rh] session-singleton-wrapper for getThemeRegistry private final static class ThemeRegistryStore extends SessionSingletonBase { private final ThemeRegistry themeRegistry; static ThemeRegistryStore getInstance() { Class clazz = ThemeRegistryStore.class; return ( ThemeRegistryStore )getInstance( clazz ); } public ThemeRegistryStore() { // RAP [rh] ThemeRegistry initialization code, copied from getThemeRegistry() themeRegistry = new ThemeRegistry(); ThemeRegistryReader reader = new ThemeRegistryReader(); reader.readThemes( Platform.getExtensionRegistry(), themeRegistry ); } public IThemeRegistry getThemeRegistry() { return themeRegistry; } } // RAP [rh] session-singleton-wrapper for getWorkingSetManager() private final static class WorkingSetManagerStore extends SessionSingletonBase { private WorkingSetManager workingSetManager; static WorkingSetManagerStore getInstance() { Class clazz = WorkingSetManagerStore.class; return ( WorkingSetManagerStore )getInstance( clazz ); } public IWorkingSetManager getWorkingSetManager( BundleContext context ) { // RAP [rh] WorkingSetManager initialization code, copied from getWorkingSetManager() if( workingSetManager == null ) { workingSetManager = new WorkingSetManager( context ); workingSetManager.restoreState(); } return workingSetManager; } } //RAP [rh] session-singleton-wrapper for getWorkingSetRegistry() private final static class WorkingSetRegistryStore extends SessionSingletonBase { private WorkingSetRegistry workingSetRegistry; static WorkingSetRegistryStore getInstance() { Class clazz = WorkingSetRegistryStore.class; return ( WorkingSetRegistryStore )getInstance( clazz ); } public WorkingSetRegistryStore() { // RAP [rh] WorkingSetRegistry initialization code, copied from getWorkingSetRegistry() workingSetRegistry = new WorkingSetRegistry(); workingSetRegistry.load(); } public WorkingSetRegistry getWorkingSetRegistry() { return workingSetRegistry; } } // RAP [rh] session-singleton-wrapper for PreferenceManager private final static class PreferenceManagerStore extends SessionSingletonBase { private final WorkbenchPreferenceManager preferenceManager; static PreferenceManagerStore getInstance() { Class clazz = PreferenceManagerStore.class; return ( PreferenceManagerStore )getInstance( clazz ); } public PreferenceManagerStore() { // RAP [rh] PreferenceManager initialization code, copied from getPreferenceManager() preferenceManager = new WorkbenchPreferenceManager( PREFERENCE_PAGE_CATEGORY_SEPARATOR ); // Get the pages from the registry PreferencePageRegistryReader registryReader = new PreferencePageRegistryReader( PlatformUI.getWorkbench() ); registryReader.loadFromRegistry( Platform.getExtensionRegistry() ); preferenceManager.addPages( registryReader.getTopLevelNodes() ); } public PreferenceManager getPreferenceManager() { return preferenceManager; } } // RAP [bm]: // /** // * Splash shell constant. // */ // private static final String DATA_SPLASH_SHELL = "org.eclipse.ui.workbench.splashShell"; //$NON-NLS-1$ // RAP [bm]: // /** // * The OSGi splash property. // * // * @sicne 3.4 // */ // private static final String PROP_SPLASH_HANDLE = "org.eclipse.equinox.launcher.splash.handle"; //$NON-NLS-1$ // RAP [bm]: // private static final String LEFT_TO_RIGHT = "ltr"; //$NON-NLS-1$ // private static final String RIGHT_TO_LEFT = "rtl";//$NON-NLS-1$ // private static final String ORIENTATION_COMMAND_LINE = "-dir";//$NON-NLS-1$ // private static final String ORIENTATION_PROPERTY = "eclipse.orientation";//$NON-NLS-1$ // private static final String NL_USER_PROPERTY = "osgi.nl.user"; //$NON-NLS-1$ // RAPEND: [bm] // Default instance of the receiver private static WorkbenchPlugin inst; // Manager that maps resources to descriptors of editors to use // RAP [bm]: replaced with session scoped one // private EditorRegistry editorRegistry; // RAPEND: [bm] // Manager for the DecoratorManager private DecoratorManager decoratorManager; // RAP [rh] themeRegistry field unneeded, replaced by session-singleton // Theme registry // private ThemeRegistry themeRegistry; // RAP [bm] workingSetManager field unneeded, replaced by session-singleton // Manager for working sets (IWorkingSet) // private WorkingSetManager workingSetManager; // RAP [rh] workingSetRegistry field unneeded, replaced by session-singleton // Working set registry, stores working set dialogs // private WorkingSetRegistry workingSetRegistry; // The context within which this plugin was started. private BundleContext bundleContext; // The set of currently starting bundles private Collection startingBundles = new HashSet(); // RAP [rh] multi-session-aware LocaleProvider service private ServiceRegistration localeProviderService; /** * Global workbench ui plugin flag. Only workbench implementation is allowed to use this flag * All other plugins, examples, or test cases must *not* use this flag. */ public static boolean DEBUG = false; /** * The workbench plugin ID. * * @issue we should just drop this constant and use PlatformUI.PLUGIN_ID instead */ public static String PI_WORKBENCH = PlatformUI.PLUGIN_ID; /** * The character used to separate preference page category ids */ public static char PREFERENCE_PAGE_CATEGORY_SEPARATOR = '/'; // Other data. // RAP [rh] replaced with session-scoped one // private WorkbenchPreferenceManager preferenceManager; // RAP [bm]: replaced with session scoped one // private ViewRegistry viewRegistry; // RAPEND: [bm] // RAP [rh] PerspectiveRegistry has session scope // private PerspectiveRegistry perspRegistry; private ActionSetRegistry actionSetRegistry; private SharedImages sharedImages; /** * Information describing the product (formerly called "primary plugin"); lazily * initialized. */ private ProductInfo productInfo = null; // RAP [bm]: not needed // private IntroRegistry introRegistry; private WorkbenchOperationSupport operationSupport; private BundleListener bundleListener; // RAP [bm]: private HttpServiceTracker httpServiceTracker; // RAPEND: [bm] /** * Create an instance of the WorkbenchPlugin. The workbench plugin is * effectively the "application" for the workbench UI. The entire UI * operates as a good plugin citizen. */ public WorkbenchPlugin() { super(); inst = this; } /** * Unload all members. This can be used to run a second instance of a workbench. */ void reset() { // RAP [bm]: // editorRegistry = null; // RAPEND: [bm] if (decoratorManager != null) { decoratorManager.dispose(); decoratorManager = null; } ProgressManager.shutdownProgressManager(); // RAP [rh] themeRegistry field unneeded, replaced by session-singleton // themeRegistry = null; // RAP [bm] workingSetManager field unneeded, replaced by session-singleton // if (workingSetManager != null) { // workingSetManager.dispose(); // workingSetManager = null; // } // RAP [rh] workingSetRegistry field unneeded, replaced by session-singleton // workingSetRegistry = null; // RAP [rh] preferenceManager field is unused since replaced with session-singleton // preferenceManager = null; // RAP [bm]: // if (viewRegistry != null) { // viewRegistry.dispose(); // viewRegistry = null; // } // RAPEND: [bm] // RAP [rh] perspRegistry field is unused, PerspectiveRegistry has session scope // if (perspRegistry != null) { // perspRegistry.dispose(); // perspRegistry = null; // } actionSetRegistry = null; sharedImages = null; productInfo = null; // RAP [bm]: not needed // introRegistry = null; if (operationSupport != null) { operationSupport.dispose(); operationSupport = null; } DEBUG = false; } /** * Creates an extension. If the extension plugin has not * been loaded a busy cursor will be activated during the duration of * the load. * * @param element the config element defining the extension * @param classAttribute the name of the attribute carrying the class * @return the extension object * @throws CoreException if the extension cannot be created */ public static Object createExtension(final IConfigurationElement element, final String classAttribute) throws CoreException { try { // If plugin has been loaded create extension. // Otherwise, show busy cursor then create extension. if (BundleUtility.isActivated(element.getDeclaringExtension() .getNamespace())) { return element.createExecutableExtension(classAttribute); } final Object[] ret = new Object[1]; final CoreException[] exc = new CoreException[1]; BusyIndicator.showWhile(null, new Runnable() { public void run() { try { ret[0] = element .createExecutableExtension(classAttribute); } catch (CoreException e) { exc[0] = e; } } }); if (exc[0] != null) { throw exc[0]; } return ret[0]; } catch (CoreException core) { throw core; } catch (Exception e) { throw new CoreException(new Status(IStatus.ERROR, PI_WORKBENCH, IStatus.ERROR, WorkbenchMessages.get().WorkbenchPlugin_extension,e)); } } /** * Answers whether the provided element either has an attribute with the * given name or a child element with the given name with an attribute * called class. * * @param element * the element to test * @param extensionName * the name of the extension to test for * @return whether or not the extension is declared */ public static boolean hasExecutableExtension(IConfigurationElement element, String extensionName) { if (element.getAttribute(extensionName) != null) return true; String elementText = element.getValue(); if (elementText != null && !elementText.equals("")) //$NON-NLS-1$ return true; IConfigurationElement [] children = element.getChildren(extensionName); if (children.length == 1) { if (children[0].getAttribute(IWorkbenchRegistryConstants.ATT_CLASS) != null) return true; } return false; } /** * Checks to see if the provided element has the syntax for an executable * extension with a given name that resides in a bundle that is already * active. Determining the bundle happens in one of two ways:<br/> * <ul> * <li>The element has an attribute with the specified name or element text * in the form <code>bundle.id/class.name[:optional attributes]</code></li> * <li>The element has a child element with the specified name that has a * <code>plugin</code> attribute</li> * </ul> * * @param element * the element to test * @param extensionName * the name of the extension to test for * @return whether or not the bundle expressed by the above criteria is * active. If the bundle cannot be determined then the state of the * bundle that declared the element is returned. */ public static boolean isBundleLoadedForExecutableExtension( IConfigurationElement element, String extensionName) { Bundle bundle = getBundleForExecutableExtension(element, extensionName); if (bundle == null) return true; return bundle.getState() == Bundle.ACTIVE; } /** * Returns the bundle that contains the class referenced by an executable * extension. Determining the bundle happens in one of two ways:<br/> * <ul> * <li>The element has an attribute with the specified name or element text * in the form <code>bundle.id/class.name[:optional attributes]</code></li> * <li>The element has a child element with the specified name that has a * <code>plugin</code> attribute</li> * </ul> * * @param element * the element to test * @param extensionName * the name of the extension to test for * @return the bundle referenced by the extension. If that bundle cannot be * determined the bundle that declared the element is returned. Note * that this may be <code>null</code>. */ public static Bundle getBundleForExecutableExtension(IConfigurationElement element, String extensionName) { // this code is derived heavily from // ConfigurationElement.createExecutableExtension. String prop = null; String executable; String contributorName = null; int i; if (extensionName != null) prop = element.getAttribute(extensionName); else { // property not specified, try as element value prop = element.getValue(); if (prop != null) { prop = prop.trim(); if (prop.equals("")) //$NON-NLS-1$ prop = null; } } if (prop == null) { // property not defined, try as a child element IConfigurationElement[] exec = element.getChildren(extensionName); if (exec.length != 0) contributorName = exec[0].getAttribute("plugin"); //$NON-NLS-1$ } else { // simple property or element value, parse it into its components i = prop.indexOf(':'); if (i != -1) executable = prop.substring(0, i).trim(); else executable = prop; i = executable.indexOf('/'); if (i != -1) contributorName = executable.substring(0, i).trim(); } if (contributorName == null) contributorName = element.getContributor().getName(); return Platform.getBundle(contributorName); } /** * Returns the image registry for this plugin. * * Where are the images? The images (typically gifs) are found in the same * plugins directory. * * @see ImageRegistry * * Note: The workbench uses the standard JFace ImageRegistry to track its * images. In addition the class WorkbenchGraphicResources provides * convenience access to the graphics resources and fast field access for * some of the commonly used graphical images. */ protected ImageRegistry createImageRegistry() { return WorkbenchImages.getImageRegistry(); } /** * Returns the action set registry for the workbench. * * @return the workbench action set registry */ public ActionSetRegistry getActionSetRegistry() { if (actionSetRegistry == null) { actionSetRegistry = new ActionSetRegistry(); } return actionSetRegistry; } /** * Return the default instance of the receiver. This represents the runtime plugin. * @return WorkbenchPlugin * @see AbstractUIPlugin for the typical implementation pattern for plugin classes. */ public static WorkbenchPlugin getDefault() { return inst; } /** * Answer the manager that maps resource types to a the * description of the editor to use * @return IEditorRegistry the editor registry used * by this plug-in. */ public IEditorRegistry getEditorRegistry() { // RAP [bm]: // if (editorRegistry == null) { // editorRegistry = new EditorRegistry(); // } // return editorRegistry; return EditorRegistry.getInstance(); // RAPEND: [bm] } /** * Answer the element factory for an id, or <code>null</code. if not found. * @param targetID * @return IElementFactory */ public IElementFactory getElementFactory(String targetID) { // Get the extension point registry. IExtensionPoint extensionPoint; extensionPoint = Platform.getExtensionRegistry().getExtensionPoint( PlatformUI.PLUGIN_EXTENSION_NAME_SPACE, IWorkbenchRegistryConstants.PL_ELEMENT_FACTORY); if (extensionPoint == null) { WorkbenchPlugin .log("Unable to find element factory. Extension point: " + IWorkbenchRegistryConstants.PL_ELEMENT_FACTORY + " not found"); //$NON-NLS-2$ //$NON-NLS-1$ return null; } // Loop through the config elements. IConfigurationElement targetElement = null; IConfigurationElement[] configElements = extensionPoint .getConfigurationElements(); for (int j = 0; j < configElements.length; j++) { String strID = configElements[j].getAttribute("id"); //$NON-NLS-1$ if (targetID.equals(strID)) { targetElement = configElements[j]; break; } } if (targetElement == null) { // log it since we cannot safely display a dialog. WorkbenchPlugin.log("Unable to find element factory: " + targetID); //$NON-NLS-1$ return null; } // Create the extension. IElementFactory factory = null; try { factory = (IElementFactory) createExtension(targetElement, "class"); //$NON-NLS-1$ } catch (CoreException e) { // log it since we cannot safely display a dialog. WorkbenchPlugin.log( "Unable to create element factory.", e.getStatus()); //$NON-NLS-1$ factory = null; } return factory; } /** * Returns the presentation factory with the given id, or <code>null</code> if not found. * @param targetID The id of the presentation factory to use. * @return AbstractPresentationFactory or <code>null</code> * if not factory matches that id. */ public AbstractPresentationFactory getPresentationFactory(String targetID) { Object o = createExtension( IWorkbenchRegistryConstants.PL_PRESENTATION_FACTORIES, "factory", targetID); //$NON-NLS-1$ if (o instanceof AbstractPresentationFactory) { return (AbstractPresentationFactory) o; } WorkbenchPlugin .log("Error creating presentation factory: " + targetID + " -- class is not an AbstractPresentationFactory"); //$NON-NLS-1$ //$NON-NLS-2$ return null; } /** * Looks up the configuration element with the given id on the given extension point * and instantiates the class specified by the class attributes. * * @param extensionPointId the extension point id (simple id) * @param elementName the name of the configuration element, or <code>null</code> * to match any element * @param targetID the target id * @return the instantiated extension object, or <code>null</code> if not found */ private Object createExtension(String extensionPointId, String elementName, String targetID) { // RAP [bm]: // IExtensionPoint extensionPoint = Platform.getExtensionRegistry() // .getExtensionPoint(PI_WORKBENCH, extensionPointId); IExtensionPoint extensionPoint = Platform.getExtensionRegistry() .getExtensionPoint(PlatformUI.PLUGIN_EXTENSION_NAME_SPACE, extensionPointId); // RAPEND: [bm] if (extensionPoint == null) { WorkbenchPlugin .log("Unable to find extension. Extension point: " + extensionPointId + " not found"); //$NON-NLS-1$ //$NON-NLS-2$ return null; } // Loop through the config elements. IConfigurationElement targetElement = null; IConfigurationElement[] elements = extensionPoint .getConfigurationElements(); for (int j = 0; j < elements.length; j++) { IConfigurationElement element = elements[j]; if (elementName == null || elementName.equals(element.getName())) { String strID = element.getAttribute("id"); //$NON-NLS-1$ if (targetID.equals(strID)) { targetElement = element; break; } } } if (targetElement == null) { // log it since we cannot safely display a dialog. WorkbenchPlugin.log("Unable to find extension: " + targetID //$NON-NLS-1$ + " in extension point: " + extensionPointId); //$NON-NLS-1$ return null; } // Create the extension. try { return createExtension(targetElement, "class"); //$NON-NLS-1$ } catch (CoreException e) { // log it since we cannot safely display a dialog. WorkbenchPlugin.log("Unable to create extension: " + targetID //$NON-NLS-1$ + " in extension point: " + extensionPointId //$NON-NLS-1$ + ", status: ", e.getStatus()); //$NON-NLS-1$ } return null; } /** * Return the perspective registry. * @return IPerspectiveRegistry. The registry for the receiver. */ public IPerspectiveRegistry getPerspectiveRegistry() { // RAP [rh]: PerspectiveRegistry has session scope // if (perspRegistry == null) { // perspRegistry = new PerspectiveRegistry(); // // the load methods can touch on WorkbenchImages if an image is // // missing so we need to wrap the call in // // a startup block for the case where a custom descriptor exists on // // startup that does not have an image // // associated with it. See bug 196352. // StartupThreading.runWithoutExceptions(new StartupRunnable() { // public void runWithException() throws Throwable { // perspRegistry.load(); // } // }); // // } // return perspRegistry; final PerspectiveRegistry result = ( PerspectiveRegistry )SessionSingletonBase.getInstance( PerspectiveRegistry.class ); ISessionStore sessionStore = RWT.getSessionStore(); Boolean initialized = ( Boolean )sessionStore.getAttribute( PERSP_REGISTRY_INITIALIZED ); if( initialized == null ) { sessionStore.setAttribute( PERSP_REGISTRY_INITIALIZED, Boolean.TRUE ); StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() throws Throwable { result.load(); } } ); } return result; } /** * Returns the working set manager * * @return the working set manager */ public IWorkingSetManager getWorkingSetManager() { // RAP [rh] WorkingSetManager must be a session-singleton // if (workingSetManager == null) { // workingSetManager = new WorkingSetManager(bundleContext); // workingSetManager.restoreState(); // } // return workingSetManager; return WorkingSetManagerStore.getInstance().getWorkingSetManager( bundleContext ); } /** * Returns the working set registry * * @return the working set registry */ public WorkingSetRegistry getWorkingSetRegistry() { // RAP [rh] WorkingSetRegistry must be a session-singleton // if (workingSetRegistry == null) { // workingSetRegistry = new WorkingSetRegistry(); // workingSetRegistry.load(); // } // return workingSetRegistry; return WorkingSetRegistryStore.getInstance().getWorkingSetRegistry(); } /** * Returns the introduction registry. * * @return the introduction registry. * @since 1.2 */ public IIntroRegistry getIntroRegistry() { // RAP [bm]: IntroRegistry must be a session-singleton // if (introRegistry == null) { // introRegistry = new IntroRegistry(); // } // return introRegistry; return (IIntroRegistry) SessionSingletonBase.getInstance(IntroRegistry.class); } /** * Returns the operation support. * * @return the workbench operation support. * @since 1.1 */ public IWorkbenchOperationSupport getOperationSupport() { if (operationSupport == null) { operationSupport = new WorkbenchOperationSupport(); } return operationSupport; } /** * Get the preference manager. * @return PreferenceManager the preference manager for * the receiver. */ public PreferenceManager getPreferenceManager() { // RAP [rh] PreferenceManager must be a session-singleton // if (preferenceManager == null) { // preferenceManager = new WorkbenchPreferenceManager( // PREFERENCE_PAGE_CATEGORY_SEPARATOR); // // //Get the pages from the registry // PreferencePageRegistryReader registryReader = new PreferencePageRegistryReader( // getWorkbench()); // registryReader // .loadFromRegistry(Platform.getExtensionRegistry()); // preferenceManager.addPages(registryReader.getTopLevelNodes()); // // } // return preferenceManager; return PreferenceManagerStore.getInstance().getPreferenceManager(); } /** * Returns the shared images for the workbench. * * @return the shared image manager */ public ISharedImages getSharedImages() { if (sharedImages == null) { sharedImages = new SharedImages(); } return sharedImages; } /** * Returns the theme registry for the workbench. * * @return the theme registry */ public IThemeRegistry getThemeRegistry() { // RAP [rh] ThemeRegistry must be a session-singleton // if (themeRegistry == null) { // themeRegistry = new ThemeRegistry(); // ThemeRegistryReader reader = new ThemeRegistryReader(); // reader.readThemes(Platform.getExtensionRegistry(), // themeRegistry); // } // return themeRegistry; return ThemeRegistryStore.getInstance().getThemeRegistry(); } /** * Answer the view registry. * @return IViewRegistry the view registry for the * receiver. */ public IViewRegistry getViewRegistry() { // RAP [bm]: // if (viewRegistry == null) { // viewRegistry = new ViewRegistry(); // } // return viewRegistry; // RAPEND: [bm] return ViewRegistry.getInstance(); } /** * Answer the workbench. * @deprecated Use <code>PlatformUI.getWorkbench()</code> instead. */ public IWorkbench getWorkbench() { return PlatformUI.getWorkbench(); } /** * Set default preference values. * This method must be called whenever the preference store is initially loaded * because the default values are not stored in the preference store. */ protected void initializeDefaultPreferences(IPreferenceStore store) { // Do nothing. This should not be called. // Prefs are initialized in WorkbenchPreferenceInitializer. } /** * Logs the given message to the platform log. * * If you have an exception in hand, call log(String, Throwable) instead. * * If you have a status object in hand call log(String, IStatus) instead. * * This convenience method is for internal use by the Workbench only and * must not be called outside the Workbench. * * @param message * A high level UI message describing when the problem happened. */ public static void log(String message) { getDefault().getLog().log( StatusUtil.newStatus(IStatus.ERROR, message, null)); } /** * Log the throwable. * @param t */ public static void log(Throwable t) { getDefault().getLog().log(getStatus(t)); } /** * Return the status from throwable * @param t throwable * @return IStatus */ public static IStatus getStatus(Throwable t) { String message = StatusUtil.getLocalizedMessage(t); return newError(message, t); } /** * Create a new error from the message and the * throwable. * @param message * @param t * @return IStatus */ public static IStatus newError(String message, Throwable t) { String pluginId = "org.eclipse.ui.workbench"; //$NON-NLS-1$ int errorCode = IStatus.OK; // If this was a CoreException, keep the original plugin ID and error // code if (t instanceof CoreException) { CoreException ce = (CoreException) t; pluginId = ce.getStatus().getPlugin(); errorCode = ce.getStatus().getCode(); } return new Status(IStatus.ERROR, pluginId, errorCode, message, StatusUtil.getCause(t)); } /** * Logs the given message and throwable to the platform log. * * If you have a status object in hand call log(String, IStatus) instead. * * This convenience method is for internal use by the Workbench only and * must not be called outside the Workbench. * * @param message * A high level UI message describing when the problem happened. * @param t * The throwable from where the problem actually occurred. */ public static void log(String message, Throwable t) { IStatus status = StatusUtil.newStatus(IStatus.ERROR, message, t); log(message, status); } /** * Logs the given throwable to the platform log, indicating the class and * method from where it is being logged (this is not necessarily where it * occurred). * * This convenience method is for internal use by the Workbench only and * must not be called outside the Workbench. * * @param clazz * The calling class. * @param methodName * The calling method name. * @param t * The throwable from where the problem actually occurred. */ public static void log(Class clazz, String methodName, Throwable t) { String msg = MessageFormat.format("Exception in {0}.{1}: {2}", //$NON-NLS-1$ new Object[] { clazz.getName(), methodName, t }); log(msg, t); } /** * Logs the given message and status to the platform log. * * This convenience method is for internal use by the Workbench only and * must not be called outside the Workbench. * * @param message * A high level UI message describing when the problem happened. * May be <code>null</code>. * @param status * The status describing the problem. Must not be null. */ public static void log(String message, IStatus status) { //1FTUHE0: ITPCORE:ALL - API - Status & logging - loss of semantic info if (message != null) { getDefault().getLog().log( StatusUtil.newStatus(IStatus.ERROR, message, null)); } getDefault().getLog().log(status); } /** * Log the status to the default log. * @param status */ public static void log(IStatus status) { getDefault().getLog().log(status); } /** * Get the decorator manager for the receiver * @return DecoratorManager the decorator manager * for the receiver. */ public DecoratorManager getDecoratorManager() { // RAP [rs]: // if (this.decoratorManager == null) { // this.decoratorManager = new DecoratorManager(); // } // return decoratorManager; return DecoratorManagerStore.getInstance().getDecoratorManager(); // RAPEND: [rs] } // TODO [bm]: move to internal util // RAP [bm]: /** * Get the http service tracker to register new servlets or resources (RAP only) * * @return ServiceTracker the http server tracker */ public HttpServiceTracker getHttpServiceTracker() { return httpServiceTracker; } // RAPEND: [bm] /* * (non-Javadoc) * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) */ public void start(BundleContext context) throws Exception { context.addBundleListener(getBundleListener()); super.start(context); bundleContext = context; Window.setDefaultOrientation(getDefaultOrientation()); JFaceUtil.initializeJFace(); // RAP [rh] regsister a multi-session-aware LocaleProvider LocaleProvider localeProvider = new SessionLocaleProvider(); String localeProviderName = LocaleProvider.class.getName(); localeProviderService = context.registerService( localeProviderName, localeProvider, new Hashtable() ); // RAP [fappel]: initialize session aware job management JobManagerAdapter.getInstance(); // RAP [fappel]: ensure that the rap http context was loaded before // the mapping of servlets from branding takes place String serviceName = HttpContextExtensionService.class.getName(); ServiceTracker httpContextExtensionServiceTracker = new ServiceTracker( context, serviceName, null ) { public Object addingService( final ServiceReference reference ) { Object result = super.addingService( reference ); httpServiceTracker = new HttpServiceTracker(context); ApplicationRegistry.registerApplicationEntryPoints(); try { BrandingExtension.read(); } catch( final IOException ioe ) { WorkbenchPlugin.log( "Unable to read branding extension", ioe ); //$NON-NLS-1$ } httpServiceTracker.open(); return result; } }; httpContextExtensionServiceTracker.open(); // RAP [fappel]: as workbench instances in RAP run in session scope the // UI bundle should be initialized in time // // The UI plugin needs to be initialized so that it can install the callback in PrefUtil, // // which needs to be done as early as possible, before the workbench // // accesses any API preferences. // Bundle uiBundle = Platform.getBundle(PlatformUI.PLUGIN_ID); // try { // // Attempt to load the activator of the ui bundle. This will force lazy start // // of the ui bundle. Using the bundle activator class here because it is a // // class that needs to be loaded anyway so it should not cause extra classes // // to be loaded.s // if(uiBundle != null) // uiBundle.start(Bundle.START_TRANSIENT); // } catch (BundleException e) { // WorkbenchPlugin.log("Unable to load UI activator", e); //$NON-NLS-1$ // } // // /* // * DO NOT RUN ANY OTHER CODE AFTER THIS LINE. If you do, then you are // * likely to cause a deadlock in class loader code. Please see Bug 86450 // * for more information. // */ } /** * Get the default orientation from the command line * arguments. If there are no arguments imply the * orientation. * @return int * @see SWT#NONE * @see SWT#RIGHT_TO_LEFT * @see SWT#LEFT_TO_RIGHT * @since 1.1 */ private int getDefaultOrientation() { String[] commandLineArgs = Platform.getCommandLineArgs(); int orientation = getCommandLineOrientation(commandLineArgs); if(orientation != SWT.NONE) { return orientation; } orientation = getSystemPropertyOrientation(); if(orientation != SWT.NONE) { return orientation; } // RAP [bm]: // return checkCommandLineLocale(); //Use the default value if there is nothing specified return SWT.NONE; // RAPEND: [bm] } // RAP [bm]: // /** // * Check to see if the command line parameter for -nl // * has been set. If so imply the orientation from this // * specified Locale. If it is a bidirectional Locale // * return SWT#RIGHT_TO_LEFT. // * If it has not been set or has been set to // * a unidirectional Locale then return SWT#NONE. // * // * Locale is determined differently by different JDKs // * and may not be consistent with the users expectations. // * // // * @return int // * @see SWT#NONE // * @see SWT#RIGHT_TO_LEFT // */ // private int checkCommandLineLocale() { // //Check if the user property is set. If not do not // //rely on the vm. // if(System.getProperty(NL_USER_PROPERTY) == null) { // return SWT.NONE; // } // // Locale locale = Locale.getDefault(); // String lang = locale.getLanguage(); // // if ("iw".equals(lang) || "he".equals(lang) || "ar".equals(lang) || //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ // "fa".equals(lang) || "ur".equals(lang)) { //$NON-NLS-1$ //$NON-NLS-2$ // return SWT.RIGHT_TO_LEFT; // } // // return SWT.NONE; // } // RAPEND: [bm] /** * Check to see if the orientation was set in the * system properties. If there is no orientation * specified return SWT#NONE. * @return int * @see SWT#NONE * @see SWT#RIGHT_TO_LEFT * @see SWT#LEFT_TO_RIGHT * @since 1.0 */ private int getSystemPropertyOrientation() { // RAP [bm]: // String orientation = System.getProperty(ORIENTATION_PROPERTY); // if(RIGHT_TO_LEFT.equals(orientation)) { // return SWT.RIGHT_TO_LEFT; // } // if(LEFT_TO_RIGHT.equals(orientation)) { // return SWT.LEFT_TO_RIGHT; // } // RAPEND: [bm] return SWT.NONE; } /** * Find the orientation in the commandLineArgs. If there * is no orientation specified return SWT#NONE. * @param commandLineArgs * @return int * @see SWT#NONE * @see SWT#RIGHT_TO_LEFT * @see SWT#LEFT_TO_RIGHT * @since 1.1 */ private int getCommandLineOrientation(String[] commandLineArgs) { //Do not process the last one as it will never have a parameter // RAP [bm]: // for (int i = 0; i < commandLineArgs.length - 1; i++) { // if(commandLineArgs[i].equalsIgnoreCase(ORIENTATION_COMMAND_LINE)){ // String orientation = commandLineArgs[i+1]; // if(orientation.equals(RIGHT_TO_LEFT)){ // System.setProperty(ORIENTATION_PROPERTY,RIGHT_TO_LEFT); // return SWT.RIGHT_TO_LEFT; // } // if(orientation.equals(LEFT_TO_RIGHT)){ // System.setProperty(ORIENTATION_PROPERTY,LEFT_TO_RIGHT); // return SWT.LEFT_TO_RIGHT; // } // } // } // RAPEND: [bm] return SWT.NONE; } /** * Return an array of all bundles contained in this workbench. * * @return an array of bundles in the workbench or an empty array if none */ public Bundle[] getBundles() { return bundleContext == null ? new Bundle[0] : bundleContext .getBundles(); } /** * Returns the bundle context associated with the workbench plug-in. * * @return the bundle context */ public BundleContext getBundleContext() { return bundleContext; } // RAP [bm]: // /** // * Returns the application name. // * <p> // * Note this is never shown to the user. // * It is used to initialize the SWT Display. // * On Motif, for example, this can be used // * to set the name used for resource lookup. // * </p> // * // * @return the application name, or <code>null</code> // * @see org.eclipse.swt.widgets.Display#setAppName // * @since 1.1 // */ // public String getAppName() { // return getProductInfo().getAppName(); // } /** * Returns the name of the product. * * @return the product name, or <code>null</code> if none */ public String getProductName() { return getProductInfo().getProductName(); } /** * Returns the image descriptors for the window image to use for this product. * * @return an array of the image descriptors for the window image, or * <code>null</code> if none */ public ImageDescriptor[] getWindowImages() { return getProductInfo().getWindowImages(); } /** * Returns an instance that describes this plugin's product (formerly "primary * plugin"). * @return ProductInfo the product info for the receiver */ private ProductInfo getProductInfo() { if (productInfo == null) { productInfo = new ProductInfo(Platform.getProduct()); } return productInfo; } /* (non-Javadoc) * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) */ public void stop(BundleContext context) throws Exception { if (bundleListener!=null) { context.removeBundleListener(bundleListener); bundleListener = null; } // RAP [rh]: clean up RAP-specific resouces if( httpServiceTracker != null ) { httpServiceTracker.close(); httpServiceTracker = null; } EntryPointExtension.unbindAll(); // RAPEND // RAP [rh] unregister multi-session-aware LocaleProvider service localeProviderService.unregister(); // TODO normally super.stop(*) would be the last statement in this // method super.stop(context); // RAP [bm] cleanup will be done in Workbench#ShutdownHandler // if (workingSetManager != null) { // workingSetManager.dispose(); // workingSetManager= null; // } // SWTResourceUtil.shutdown(); // RAPEND } /** * Return the new wizard registry. * * @return the new wizard registry */ public IWizardRegistry getNewWizardRegistry() { return NewWizardRegistry.getInstance(); } /** * Return the import wizard registry. * * @return the import wizard registry */ public IWizardRegistry getImportWizardRegistry() { return ImportWizardRegistry.getInstance(); } /** * Return the export wizard registry. * * @return the export wizard registry */ public IWizardRegistry getExportWizardRegistry() { return ExportWizardRegistry.getInstance(); } /** * FOR INTERNAL WORKBENCH USE ONLY. * * Returns the path to a location in the file system that can be used * to persist/restore state between workbench invocations. * If the location did not exist prior to this call it will be created. * Returns <code>null</code> if no such location is available. * * @return path to a location in the file system where this plug-in can * persist data between sessions, or <code>null</code> if no such * location is available. */ public IPath getDataLocation() { try { return getStateLocation(); } catch (IllegalStateException e) { // This occurs if -data=@none is explicitly specified, so ignore this silently. // Is this OK? See bug 85071. return null; } } /* package */ void addBundleListener(BundleListener bundleListener) { bundleContext.addBundleListener(bundleListener); } /* package */ void removeBundleListener(BundleListener bundleListener) { bundleContext.removeBundleListener(bundleListener); } /* package */ int getBundleCount() { return bundleContext.getBundles().length; } /* package */ OutputStream getSplashStream() { // assumes the output stream is available as a service // see EclipseStarter.publishSplashScreen ServiceReference[] ref; try { ref = bundleContext.getServiceReferences(OutputStream.class.getName(), null); } catch (InvalidSyntaxException e) { return null; } if(ref==null) { return null; } for (int i = 0; i < ref.length; i++) { String name = (String) ref[i].getProperty("name"); //$NON-NLS-1$ if (name != null && name.equals("splashstream")) { //$NON-NLS-1$ Object result = bundleContext.getService(ref[i]); bundleContext.ungetService(ref[i]); return (OutputStream) result; } } return null; } /** * @return */ private BundleListener getBundleListener() { if (bundleListener == null) { bundleListener = new SynchronousBundleListener() { public void bundleChanged(BundleEvent event) { WorkbenchPlugin.this.bundleChanged(event); } }; } return bundleListener; } private void bundleChanged(BundleEvent event) { // a bundle in the STARTING state generates 2 events, LAZY_ACTIVATION // when it enters STARTING and STARTING when it exists STARTING :-) synchronized (startingBundles) { switch (event.getType()) { case BundleEvent.STARTING : startingBundles.add(event.getBundle()); break; case BundleEvent.STARTED : case BundleEvent.STOPPED : startingBundles.remove(event.getBundle()); break; default : break; } } } public boolean isStarting(Bundle bundle) { synchronized (startingBundles) { return startingBundles.contains(bundle); } } /** * Return whether or not the OSGi framework has specified the handle of a splash shell. * * @return whether or not the OSGi framework has specified the handle of a splash shell * @since 1.1 */ public static boolean isSplashHandleSpecified() { // RAP [bm]: // return System.getProperty(PROP_SPLASH_HANDLE) != null; return false; // RAPEND: [bm] } // RAP [bm]: // /** // * Get the splash shell for this workbench instance, if any. This will find // * the splash created by the launcher (native) code and wrap it in a SWT // * shell. This may have the side effect of setting data on the provided // * {@link Display}. // * // * @param display // * the display to parent the shell on // * // * @return the splash shell or <code>null</code> // * @throws InvocationTargetException // * @throws IllegalAccessException // * @throws IllegalArgumentException // * @throws NumberFormatException // * @see Display#setData(String, Object) // * @since 3.4 // */ // public static Shell getSplashShell(Display display) // throws NumberFormatException, IllegalArgumentException, // IllegalAccessException, InvocationTargetException { // Shell splashShell = (Shell) display.getData(DATA_SPLASH_SHELL); // if (splashShell != null) // return splashShell; // // String splashHandle = System.getProperty(PROP_SPLASH_HANDLE); // if (splashHandle == null) { // return null; // } // // // look for the 32 bit internal_new shell method // try { // Method method = Shell.class.getMethod( // "internal_new", new Class[] { Display.class, int.class }); //$NON-NLS-1$ // // we're on a 32 bit platform so invoke it with splash // // handle as an int // splashShell = (Shell) method.invoke(null, new Object[] { display, // new Integer(splashHandle) }); // } catch (NoSuchMethodException e) { // // look for the 64 bit internal_new shell method // try { // Method method = Shell.class // .getMethod( // "internal_new", new Class[] { Display.class, long.class }); //$NON-NLS-1$ // // // we're on a 64 bit platform so invoke it with a long // splashShell = (Shell) method.invoke(null, new Object[] { // display, new Long(splashHandle) }); // } catch (NoSuchMethodException e2) { // // cant find either method - don't do anything. // } // } // // display.setData(DATA_SPLASH_SHELL, splashShell); // return splashShell; // } // RAP [bm]: // /** // * Removes any splash shell data set on the provided display and disposes // * the shell if necessary. // * // * @param display // * the display to parent the shell on // * @since 3.4 // */ // public static void unsetSplashShell(Display display) { // Shell splashShell = (Shell) display.getData(DATA_SPLASH_SHELL); // if (splashShell != null) { // if (!splashShell.isDisposed()) // splashShell.dispose(); // display.setData(DATA_SPLASH_SHELL, null); // } // // } }